Threads are facing deadlock in socket program [migrated]

Posted by ankur.trapasiya on Programmers See other posts from Programmers or by ankur.trapasiya
Published on 2012-04-13T12:50:00Z Indexed on 2012/04/13 17:42 UTC
Read the original article Hit count: 368

Filed under:
|
|

I am developing one program in which a user can download a number of files. Now first I am sending the list of files to the user. So from the list user selects one file at a time and provides path where to store that file. In turn it also gives the server the path of file where does it exist.

I am following this approach because I want to give stream like experience without file size limitation.

Here is my code..

1) This is server which gets started each time I start my application

public class FileServer extends Thread {

    private ServerSocket socket = null;

    public FileServer() {
        try {
            socket = new ServerSocket(Utils.tcp_port);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public void run() {

        try {

            System.out.println("request received");
            new FileThread(socket.accept()).start();

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

}

2) This thread runs for each client separately and sends the requested file to the user 8kb data at a time.

public class FileThread extends Thread {

    private Socket socket;
    private String filePath;



    public String getFilePath() {
        return filePath;
    }

    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }

    public FileThread(Socket socket) {
        this.socket = socket;
        System.out.println("server thread" + this.socket.isConnected());
        //this.filePath = filePath;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try

        {
            ObjectInputStream ois=new ObjectInputStream(socket.getInputStream());
            try {
                           //************NOTE
                filePath=(String) ois.readObject();             
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            File f = new File(this.filePath);

            byte[] buf = new byte[8192];

            InputStream is = new FileInputStream(f);
            BufferedInputStream bis = new BufferedInputStream(is);

            ObjectOutputStream oos = new ObjectOutputStream(
                    socket.getOutputStream());
            int c = 0;

            while ((c = bis.read(buf, 0, buf.length)) > 0) {
                oos.write(buf, 0, c);
                oos.flush();
                // buf=new byte[8192];
            }

            oos.close();
            //socket.shutdownOutput();
            // client.shutdownOutput();
            System.out.println("stop");
            // client.shutdownOutput();
            ois.close();
//          Thread.sleep(500);

            is.close();
            bis.close();
            socket.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

    }

}

NOTE: here filePath represents the path of the file where it exists on the server. The client who is connecting to the server provides this path. I am managing this through sockets and I am successfully receiving this path.

3) FileReceiverThread is responsible for receiving the data from the server and constructing file from this buffer data.

public class FileReceiveThread extends Thread {

    private String fileStorePath;
    private String sourceFile;
    private Socket socket = null;

    public FileReceiveThread(String ip, int port, String fileStorePath,
            String sourceFile) {
        this.fileStorePath = fileStorePath;
        this.sourceFile = sourceFile;
        try {
            socket = new Socket(ip, port);
            System.out.println("receive file thread " + socket.isConnected());
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public void run() {
        try {
            ObjectOutputStream oos = new ObjectOutputStream(
                    socket.getOutputStream());
            oos.writeObject(sourceFile);
            oos.flush();
            // oos.close();
            File f = new File(fileStorePath);

            OutputStream os = new FileOutputStream(f);
            BufferedOutputStream bos = new BufferedOutputStream(os);

            byte[] buf = new byte[8192];
            int c = 0;

            //************ NOTE

            ObjectInputStream ois = new ObjectInputStream(
                    socket.getInputStream());

            while ((c = ois.read(buf, 0, buf.length)) > 0) {
                // ois.read(buf);
                bos.write(buf, 0, c);
                bos.flush();
                // buf = new byte[8192];
            }

            ois.close();
            oos.close();
            //
            os.close();
            bos.close();

             socket.close();
            //Thread.sleep(500);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

}

NOTE : Now the problem that I am facing is at the first time when the file is requested the outcome of the program is same as my expectation. I am able to transmit any size of file at first time. Now when the second file is requested (e.g. I have sent file a,b,c,d to the user and user has received file a successfully and now he is requesting file b) the program faces deadlock at this situation. It is waiting for socket's input stream. I put breakpoint and tried to debug it but it is not going in FileThread's run method second time. I could not find out the mistake here. Basically I am making a LAN Messenger which works on LAN. I am using SWT as UI framework.

© Programmers or respective owner

Related posts about java

Related posts about multithreading